/**   
 * @title MapCommonUtil.java 
 * @package com.hopechart.mapcomponent.util
 * @description 地图业务公共部分工具类 
 * @author daijiang@hopechart.com
 * @date 2015年9月18日 上午10:56:40 
 * @version v1.0.0
 * @copyright 杭州鸿泉数字设备有限公司
 */
package com.baikeyang.bike.util;

import java.util.List;

import org.apache.log4j.Logger;

import com.baikeyang.bike.bean.LatLng;

/** 
 * @className MapCommonUtil 
 * @description 地图业务公共部分工具类  
 * @author daijiang@hopechart.com
 * @date 2015年9月18日 上午10:56:40 
 *  
 */
public class MapCommonUtil {
    
    private static Logger log = Logger.getLogger(MapCommonUtil.class);


    /**
     * @title distanceByLngLat 
     * @description 计算两点间距离
     * @param lng1 第一个点位经度
     * @param lat1 第一个点位纬度
     * @param lng2 第二个点位经度
     * @param lat2 第二个点位纬度
     * @return double
     * @throws
     */
    public static double distanceByLngLat(double lng1, double lat1, double lng2, double lat2) {
        if((lng1==0 && lat1==0) || (lng2==0 && lat2==0)) {
            return -1;
        }
        double radLat1 = lat1 * Math.PI / 180;
        double radLat2 = lat2 * Math.PI / 180;
        double a = radLat1 - radLat2;
        double b = lng1 * Math.PI / 180 - lng2 * Math.PI / 180;
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1)
                * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * 6378137.0;// 取WGS84标准参考椭球中的地球长半径(单位:m)
        return Math.round(s * 10000) / 10000;
    }
    
    
    /**
     * 判断点是否在圆形区域内
     * @param pointLng 点的经度
     * @param pointLat 点的纬度
     * @param cenLngX 圆的中心点经度
     * @param cenLatY 圆的中心点纬度
     * @param radius 半径，单位：米
     * @return 
     */
    public static boolean isPointInCircleArea(double pointLng, double pointLat, double cenLngX, double cenLatY, double radius) {
        boolean result = false;
        
        double dDistance = -1;
        if ((pointLng == 0 && pointLat == 0) || (cenLngX == 0 && cenLatY == 0)) {
            return result;
        } 
        
        double radLat1 = pointLat * Math.PI / 180;
        double radLat2 = cenLatY * Math.PI / 180;
        double a = radLat1 - radLat2;
        double b = pointLng * Math.PI / 180 - cenLngX * Math.PI / 180;
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1)
                * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * 6378137.0;// 取WGS84标准参考椭球中的地球长半径(单位:m)
        dDistance = Math.round(s * 10000) / 10000;
        
        return (dDistance <= radius);
    }
    
    //计算点是否在区域（矩形，多边形）范围内：最后一个点与第一个点不相同
    public static boolean isPointInArea(LatLng latlng, List<LatLng> llList) {
        if (latlng!=null && llList!=null) {
            int nCount = llList.size();
            int nCross = 0;
            for (int i = 0; i < nCount; i++) {
                LatLng p1 = llList.get(i);
                double plng1 = p1.getLng();
                double plat1 = p1.getLat();
                LatLng p2 = llList.get((i + 1) % nCount);
                double plng2 = p2.getLng();
                double plat2 = p2.getLat();
                // 求解 y=p.y 与 p1p2 的交点
                if ( plat1 == plat2 ) continue;                             // p1p2 与 y=p0.y平行
                if ( latlng.getLat() < Math.min(plat1, plat2) ) continue;   // 交点在p1p2延长线上
                if ( latlng.getLat() >= Math.max(plat1, plat2) ) continue;  // 交点在p1p2延长线上
                // 求交点的 X 坐标 --------------------------------------------------------------
                double x = (double)(latlng.getLat() - plat1) * (double)(plng2 - plng1) / (double)(plat2 - plat1) + plng1;
                if ( x > latlng.getLng() ) {
                    nCross++; // 只统计单边交点
                }
            }
            // 单边交点为偶数，点在多边形之外
            return (nCross % 2 == 1);
        }
        return false;
    }
    
    /**
     * 获取线路的长度
     * @param lnglats
     * @return
     */
    public static double getRouteLength(String lnglats){
        String[] arr = lnglats.split(";");
        double distance = 0d;
        double tempDis = 0d;
        for (int i = 0; i < arr.length; i++) {
            tempDis = 0d;
            if (i == arr.length-1) {
                break;
            }
            String[] lnglat1 = arr[i].split(",");
            String[] lnglat2 = arr[i+1].split(",");
            double lng1 = Double.valueOf(lnglat1[0]);
            double lat1 = Double.valueOf(lnglat1[1]);
            double lng2 = Double.valueOf(lnglat2[0]);
            double lat2 = Double.valueOf(lnglat2[1]);
            tempDis = distanceByLngLat(lng1, lat1, lng2, lat2);
            distance += tempDis;
        }
        return distance;
    }
}
